package interview.lingxing;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 交替打印数字和字母
 */
public class Test2 {
    /**
     * 线程池 固定大小线程池
     */
    private static ExecutorService executor = Executors.newFixedThreadPool(2);

    public static void main(String[] args) throws InterruptedException {
        // 原子计数器，用于控制打印顺序
        AtomicInteger atomicInteger = new AtomicInteger(0);
        // 设置公平锁 保证两个线程是交替打印
        ReentrantLock lock = new ReentrantLock(true);

        executor.execute(new PrintTask(atomicInteger, lock, true));
        // 保证第一个任务能执行成功
        Thread.sleep(10);
        executor.execute(new PrintTask(atomicInteger, lock, false));
    }

    /**
     * 打印任务
     */
    static class PrintTask implements Runnable {

        private AtomicInteger atomicInteger;

        private ReentrantLock lock;

        private boolean throwException;

        public PrintTask(AtomicInteger atomicInteger, ReentrantLock lock, boolean throwException) {
            this.atomicInteger = atomicInteger;
            this.lock = lock;
            this.throwException = throwException;
        }

        @Override
        public void run() {
            // 代码里不建议死循环，为了方便演示才这么做，可以用一个变量控制打印次数
            while (true) {
                lock.lock();
                try {
                    int mod = atomicInteger.get() % 6;
                    switch (mod) {
                        case 0:
                            System.out.println("1");
                            break;
                        case 1:
                            System.out.println("A");
                            break;
                        case 2:
                            System.out.println("2");
                            break;
                        case 3:
                            System.out.println("B");
                            break;
                        case 4:
                            System.out.println("3");
                            break;
                        case 5:
                            System.out.println("C");
                            break;
                        default:
                            break;
                    }
                    atomicInteger.incrementAndGet();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                    if (throwException) {
                        throw new RuntimeException("xxx");
                    }
                }
            }
        }
    }
}
